-----------------------本地的cmd请求
local filename = "nodecmd.lua"
local skynet = require "skynet"
local cluster = require "skynet.cluster"
require "skynet.manager"

local configdao = require "configdao"
local timetool = require "timetool"
local filelog = require "filelog"
local tabletool = require "tabletool"

require "cpcqsscenum"

local CMD = {}
local service = nil

function CMD.init(caller)
	service = caller -- 这里的caller，是router
end

function CMD.cmd(msg,...)
    if not msg then return end
    local f = CMD[msg]
    if not f then
        return
    end

    return f(...)
end

-----------------------------------------------

--
-- 删除桌子
-- 由游戏节点发来
--
function CMD.delete_table(table_index)
    filelog.print("------------delete table",table_index)
    if not table_index then
        return
    end

    table_index = tonumber(table_index) or 0
    local item = service.index_to_table[table_index]

    --删除大厅节点的code--index映射
    if item then
        local status,result = skynet.pcall(cluster.send,"hallnode", ".router","del_table_code",item.code,skynet.getenv("nodename"), table_index)
        service.code_to_index[item.code] = nil
    end
    service.index_to_table[table_index] = nil
  
end

--
--离桌
--
function CMD.leave_table(rid,table_index,coin)
    service:unforward(rid,table_index,coin)
end

--
--进桌
--
function CMD.notice_gate_entertable(rid,table_service,table_index,coin)
    service:forward(rid,table_service,table_index,coin)
end

--
--获得桌子所有玩家rid
--
function CMD.gettableallrid(table_index)
    if table_index == nil then
        return {}
    end

    local rids = nil
    local item = service.index_to_table[table_index]
    if item then
        rids = skynet.call(item.table_service,"lua","cmd","get_table_allrid")
    end

    return {rids = rids}
end

--
--获得游戏状态：游戏中人数，等待人数，总人数，桌子数
--（不包括练习场）
--
function CMD.getgamestate()
    --金币场信息
    local coin_level_msg = { }
    for i = 1,3 do
        coin_level_msg[i] = {
            total_player = 0,       --总玩家数
            table_num = 0,          --桌子数量
            ingame_player = 0,      --游戏中玩家数
            wait_player = 0,        --旁观玩家数
        }
    end

    --钻石场信息
    local diamond_level_msg = { }
    for i = 1,3 do
        diamond_level_msg[i] = {
            total_player = 0,       --总玩家数
            table_num = 0,          --桌子数量
            ingame_player = 0,      --游戏中玩家数
            wait_player = 0,        --旁观玩家数
        }
    end

    local status = false
    for index,item in pairs(service.index_to_table) do
        status,data = skynet.pcall(skynet.call,item.table_service,"lua","cmd","gettablestate")
        if status and data then
            local msg = nil
            if data.table_type == ECQSSCTableType.TABLE_TYPE_COIN then       --金币场
                    msg = coin_level_msg[data.level_type]
            elseif data.table_type == ECQSSCTableType.TABLE_TYPE_DIAMOND then
                msg = diamond_level_msg[data.level_type]
            end

            if msg then
                msg.total_player = msg.total_player + data.cur_player_num
                msg.table_num = msg.table_num + 1
                if data.is_ingame then
                    msg.ingame_player = msg.ingame_player + data.cur_player_num
                else
                    msg.wait_player = msg.wait_player + data.cur_player_num
                end
            end
        end
    end
    
    local response = {
        zijian_diamond = 0,
        zijian_coin = 0,
    }
    for _,item in pairs(coin_level_msg) do
        response.zijian_coin = response.zijian_coin + item.total_player
    end
    for _,item in pairs(diamond_level_msg) do
        response.zijian_diamond = response.zijian_diamond + item.total_player
    end
    filelog.print("----game state--------", response)
    return response
end

--
--强制删除桌子
--
function CMD.destroytable(table_code, table_index)
    local responsemsg = { }
    local index = service.code_to_index[table_code] 
    if not index or not service.index_to_table[index] then
        responsemsg.retcode = EErrCode.ERR_INVALID_REQUEST
        responsemsg.retstr = "桌子不存在！"
        return responsemsg
    end

    local svr = service.index_to_table[index].table_service
    skynet.send(svr,"lua","cmd","delete",ECQSSCTableDeleteReason.DELETE_REASON_SYSTEM_REQUIRE)

    return responsemsg
end

--
--获得桌子状态
--
function CMD.gettablestate(table_code)
    local responsemsg = { }
    local index = service.code_to_index[table_code] 
    if not index or not service.index_to_table[index] then
        responsemsg.retcode = EErrCode.ERR_INVALID_REQUEST
        responsemsg.retstr = "桌子不存在！"
        return responsemsg
    end

    local svr = service.index_to_table[index].table_service
    local msg = skynet.call(svr,"lua","cmd","gettablestate")

    return msg
end

--
--检测游戏状态,心跳超时的桌子将被删除
--
function CMD.checkgamestate()
    local outtime = 60      --心跳超时60s
    local cur_time = timetool.get_time()

    --检测所有桌子
    for index,item in pairs(service.index_to_table) do
        status,tableinfo = skynet.pcall(skynet.call,item.table_service,"lua","cmd","gettablestate")
        if status and tableinfo then
            if tableinfo.table_type == ECQSSCTableType.TABLE_TYPE_DIAMOND then
                local last_heart_time = tableinfo.last_heart_time or 0
                local cur_player_num = tableinfo.cur_player_num or 0
                local is_deleteing = tableinfo.is_deleteing or false
                local is_can_delete = false
                local is_delete_by_timer = true

                if tableinfo.is_ingame then
                    if cur_time - last_heart_time > outtime then
                        is_can_delete = true
                        is_delete_by_timer = false
                    end
                else
                    if cur_player_num <= 0 then
                         is_can_delete = true
                    end
                end 
                if is_can_delete and not is_deleteing then
                    -- if is_delete_by_timer then
                    --     skynet.send(item.table_service,"lua","cmd","delete_table_by_timer")
                    -- else
                    --     skynet.send(item.table_service,"lua","cmd","delete",ECQSSCTableDeleteReason.DELETE_REASON_SYSTEM_ERROR)
                    -- end
                end
            end
        end
    end  
end

--
--获得游戏节点数据
--
function CMD.get_gamenode_data()
    local codelist = { }

    --获得桌子列表
    for index,item in pairs(service.index_to_table) do
        status,data = skynet.pcall(skynet.call,item.table_service,"lua","cmd","get_table_data")
        if status and data then
            codelist[data.table_code] = {
                table_index = data.table_index,
                create_rid = data.create_rid,
                conf = tabletool.deepcopy(data.conf),
                create_time = data.create_time,
            }
        end
    end

    return codelist
end

--
--设置桌子结束标记
--
function CMD.set_tableend_flag(table_code)
    if not table_code or not service.code_to_index[table_code] then
        return false
    end

    local is_ok = false 
    local table_index = service.code_to_index[table_code]
    local item = service.index_to_table[table_index]
    if item and item.table_service then 
        skynet.send(item.table_service,"lua","cmd","set_tableend_flag")
    end
end

--
--设置游戏服结束标记
--
function CMD.set_gameend_flag()
    service.gameend_flag = true

    --删掉所有等待桌,并给游戏中桌子设置结束标记
    for index,item in pairs(service.index_to_table) do
        status,tableinfo = skynet.pcall(skynet.call,item.table_service,"lua","cmd","gettablestate")
        if status and tableinfo and not tableinfo.is_deleteing then
            if tableinfo.table_state == ECQSSCTableState.TABLE_STATE_WAIT_GAME_START
                or tableinfo.table_state == ECQSSCTableState.TABLE_STATE_GAME_START then
                skynet.send(item.table_service, "lua", "cmd", "delete", ECQSSCTableDeleteReason.DELETE_REASON_SYSTEM_ERROR)
            else
                skynet.send(item.table_service, "lua", "cmd", "set_tableend_flag")
            end
        end
    end

    --重置机器人
    skynet.send(".robotmgr", "lua", "reset_robots")
end

--
--清除玩家状态
--
function CMD.clear_player_state(rid)
    if not rid or rid <= 0 then
        return
    end

    if service.role_map[rid] then
        local item = service.role_map[rid]
        if item.table_service then
            local status,result = skynet.pcall(skynet.call, item.table_service, "lua", "request", "leavetable", rid, {}, {})
            if not status or result.retcode ~= nil then
                service:unforward(rid, item.table_index, 0)
            end
            return
        end
        service:unforward(rid, item.table_index, 0)
    end
end

--
--更新权值表
--
function CMD.update_weight_list(new_w_list)
    skynet.send(".slotmgr", "lua", "update_picture_weight_list", new_w_list)
end

--
--设置系统输钱上限
--
function CMD.set_system_lose_limit(loselimit_base, loselimit_factor)
    skynet.send(".slotmgr", "lua", "set_system_lose_limit", loselimit_base, loselimit_factor)
end

--
--设置机器人状态
--
function CMD.set_game_robot_state(is_run)
    skynet.send(".robotmgr", "lua", "set_game_robot_state", is_run)
end

--
--获得机器人状态
--
function CMD.get_game_robot_state()
    return skynet.call(".robotmgr", "lua", "get_game_robot_state")
end

--
--获得机器人数目
--
function CMD.get_game_robot_num()
    return skynet.call(".robotmgr", "lua", "get_game_robot_num")
end

--
--设置机器人数量
--
function CMD.set_game_robot_num(base_num, inc_factor, min_num)
    skynet.send(".robotmgr", "lua", "set_game_robot_num", base_num, inc_factor, min_num)
end

return CMD